Dieses Kapitel befasst sich mit dem Thema Datenmodellierung mit UML. Ziel ist es, die Unified Modeling Language – kurz UML – als Notation zu verstehen. Wir konzentrieren uns dabei auf das UML-Klassendiagramm, das in der Version 2.5 verwendet wird und in der Software- und Datenbankentwicklung eine zentrale Rolle spielt. In unserem Kontext sind Operationen und Methoden nicht relevant; wir interessieren uns ausschließlich für Klassen, Attribute und deren Beziehungen. Wichtig ist dabei die Lesbarkeit. Eine Klasse wird durch ein Rechteck dargestellt, das im oberen Teil den Namen der Entität und im unteren Teil die Attribute mit ihrer Sichtbarkeit (gekennzeichnet durch Plus- und Minuszeichen) und den Datentypen enthält. Zwischen den Klassen werden Linien gezogen, die mit Multiplizitäten und Leserichtungen versehen sind. Diese zeigen, wie viele Objekte miteinander verknüpft sind und in welche Richtung die Beziehung besteht. Innerhalb der UML-Klassen werden Attribute typischen Java-Datentypen zugeordnet. Neben primitiven Typen wie int oder boolean kommen auch komplexere Typen wie String, Date und BigDecimal zum Einsatz. Diese Zuweisungen erleichtern spätere Umsetzungen in Java oder relationalen Datenbanken. Ein wichtiger Aspekt bei der Modellierung sind die sogenannten Multiplizitäten. Diese legen fest, wie viele Objekte einer Klasse mit Objekten einer anderen Klasse verbunden sein können oder müssen. Beziehungen dieser Art werden Assoziationen genannt. Ein Stern (*) steht für beliebig viele Objekte, eine Eins (1) für genau ein Objekt. Kombinationen wie „0..2“ oder „3..*“ geben flexible oder verpflichtende Beziehungen an. Ein praktisches Beispiel hierzu ist das Simultanschach: Ein Spieler spielt gleichzeitig zwischen einer und acht Partien. Jede Partie wiederum besteht genau aus zwei Spielern. An diesem Beispiel wird deutlich, wie praxisnahe Beziehungen mittels Multiplizitäten modelliert werden können. Ein weiteres Beispiel stammt aus dem Bankwesen: Ein Kunde muss mindestens ein Konto besitzen, jedes Konto wiederum gehört immer genau einem Kunden. Wird der Kunde gelöscht, muss auch das Konto entfernt werden. Für Depots gilt, dass ein Kunde null oder beliebig viele Depots besitzen kann. Jedes Depot gehört genau zu einem Kunden und wird ebenfalls gelöscht, wenn der Kunde entfernt wird. Neben der Multiplizität ist auch die Navigierbarkeit einer Assoziation entscheidend. Diese beschreibt die Richtung, in der eine Beziehung durchlaufen werden kann. Eine Beziehung, bei der ein Pfeil von Klasse A zu Klasse B zeigt, besagt, dass ein Objekt der Klasse A auf ein Objekt der Klasse B zugreifen kann, aber nicht unbedingt umgekehrt. Ob eine Beziehung einseitig oder beidseitig navigierbar ist, wird durch Pfeile dargestellt. Navigierbarkeit setzt voraus, dass ein Objekt eine Referenz auf ein anderes besitzt. Die Referenz ist somit das Bindeglied zwischen Objekten. Wenn beispielsweise jedes Tier einen Namen haben soll, muss jedes Tier-Objekt bei seiner Erstellung eine Referenz namens „name“ auf ein Objekt der Klasse String besitzen. Diese Referenz kann dabei auch null sein, wodurch bereits die Möglichkeit zur Kenntnis eines anderen Objektes gegeben ist. Wenn eine Assoziation selbst Attribute besitzt, spricht man von einer sogenannten Assoziationsklasse. Ein Beispiel hierfür ist ein Lieferant, der ein Produkt mit einem individuellen Rabatt abhängig von der Menge liefert. Diese zusätzlichen Informationen gehören nicht zum Lieferanten oder zum Produkt, sondern explizit zur Beziehung zwischen beiden und werden deshalb als eigene Klasse modelliert. In komplexeren Situationen können mehr als zwei Klassen über eine dritte Klasse miteinander verbunden werden. Diese dritte Klasse steht oft für etwas Organisatorisches oder Virtuelles, wie etwa ein Verkaufsgespräch, das einen Interessenten, einen Verkäufer und ein Produkt miteinander verbindet. Solche mehrgliedrigen Assoziationen werden in UML mit einer Raute dargestellt. Ein weiteres wichtiges Konzept in UML ist die Vererbung, auch Generalisierung oder Spezialisierung genannt. Die Oberklasse enthält gemeinsame Merkmale, während Unterklassen diese verfeinern oder ergänzen. Ein Objekt der Unterklasse ist gleichzeitig ein Objekt der Oberklasse. Vererbung wird in UML durch einen Pfeil mit weißer Spitze dargestellt, der von der Unterklasse zur Oberklasse zeigt. Typische Beispiele für Vererbung finden sich in Bereichen wie dem Tierreich oder der Kundenverwaltung: Die Oberklasse „Person“ wird in „Kunde“, „Mitarbeiter“, „Student“ oder „Lieferant“ spezifiziert. Im Tierreich sind beispielsweise „Katze“, „Hund“ und „Maus“ Unterklassen der Oberklasse „Tier“. Eine noch speziellere Unterklasse wäre etwa die „Dogge“, die eine spezialisierte Form des Hundes darstellt und damit gleichzeitig auch Unterklasse von „Tier“ ist. Um Vererbungsstrukturen klarer abzugrenzen, wird ein sogenannter Diskriminator eingesetzt. Er gibt an, nach welchem eindeutigen Kriterium die Vererbung unterschieden wird. So könnten spezielle Angestellte einmal anhand der Arbeitszeit und einmal anhand ihrer Tätigkeit unterschieden werden. Ein Diskriminator hilft dabei, Überlagerungen und Mehrfachvererbungen zu vermeiden, die häufig fehleranfällig sind. Zwei weitere Konzepte sind Aggregation und Komposition, die beide eine Teil-Ganzes-Beziehung beschreiben. Bei einer Aggregation kann das Teil unabhängig vom Ganzen existieren. Bei einer Komposition hingegen ist das Teil zwingend vom Ganzen abhängig: Wird das Ganze gelöscht, muss auch das Teil entfernt werden. Ein klassisches Beispiel für eine Komposition ist die Beziehung zwischen Haus und Raum: Ein Haus besteht aus mehreren Räumen, aber ein Raum kann nicht ohne ein Haus existieren. Ein Beispiel für eine Aggregation wäre die Beziehung zwischen einer Übungsgruppe und ihren Studenten: Ein Student kann Teil einer Übungsgruppe sein, aber auch ohne diese Gruppe existieren. Zur weiteren Verdeutlichung betrachten wir zwei Beispiele für Aggregation: Ein Dreieck besteht aus genau drei Punkten, wobei ein Punkt aber auch ohne ein Dreieck existieren kann. Ein Auto besteht aus Rädern, wobei jedes Rad unabhängig vom Auto existieren kann. Zum Abschluss ein Beispiel für Komposition: Ein Verzeichnis enthält beliebig viele Dateien. Eine Datei existiert nur innerhalb eines Verzeichnisses. Wird das Verzeichnis gelöscht, verschwinden auch die enthaltenen Dateien. Zwar können Dateien als Datenströme übertragen werden, aber dann handelt es sich nicht mehr um Dateien im Sinne des Dateisystems. Diese starke Abhängigkeit von Teil zu Ganzem ist charakteristisch für eine Komposition.